﻿using SdmxMl.Structure;
using System;
using System.Text;

namespace SasPlugIn.DB
{
    /// <summary>SAS Table generation code</summary>
    public class SasTableGenerator : TableGenerator
    {
        #region Constructor

        public SasTableGenerator(DbTable table) : base(table) { }

        #endregion

        #region Methods overriding

        /// <summary>DB instructions for Drop and re-create table  </summary>
        protected override void CreateTable(string tableName)
        {
            string prefixDot = string.IsNullOrEmpty(table.Prefix) ? string.Empty : table.Prefix + ".";

            sb.Append("drop table ").Append(prefixDot).Append(tableName).Append(';').Append(Environment.NewLine);
            sb.Append("create table ").Append(prefixDot).Append(tableName);
        }

        protected override void StartColumns()
        {
            sb.Append('(');
        }

        public override void GenerateColumn(StringBuilder sb, DbColumn column)
        {
            // Name
            sb.Append(column.Name).Append(' ');

            // Format
            switch (column.TFormat.TextType)
            {
                case TextTypeType.Integer:
                case TextTypeType.Long:
                    sb.Append("NUM FORMAT=").Append(GetNumericColumnLen(column.TFormat, 11)).Append(".0");
                    break;

                case TextTypeType.Short:
                    sb.Append("NUM FORMAT=").Append(GetNumericColumnLen(column.TFormat, 6)).Append(".0");
                    break;

                case TextTypeType.BigInteger:
                    sb.Append("NUM FORMAT=").Append(GetNumericColumnLen(column.TFormat, 20)).Append(".0");
                    break;

                // num format=DATE9. ,DATE9X,
                case TextTypeType.Date:
                    sb.Append("DATE9X");
                    break;

                // Decimal
                case TextTypeType.Decimal:
                case TextTypeType.Float:
                case TextTypeType.Double:
                    if (string.IsNullOrEmpty(column.TFormat.decimals.Trim()) == false && string.IsNullOrEmpty(column.TFormat.maxLength.Trim()) == false)
                    {
                        sb.Append("NUM FORMAT=").Append(column.TFormat.maxLength.Trim()).Append('.').Append(column.TFormat.decimals.Trim());
                    }
                    else
                    {
                        sb.Append("NUM");
                    }
                    break;

                case TextTypeType.Boolean:
                    sb.Append("CHAR(1)");
                    break;

                case TextTypeType.Year:
                    sb.Append("CHAR(4)");
                    break;

                case TextTypeType.String:
                default:
                    int len = GetCharColumnLen(column.TFormat);
                    sb.Append("CHAR(").Append(len).Append(")");
                    break;
            }
            sb.Append(',');
        }

        protected override void FinalizeColumns()
        {
            sb.Remove(sb.Length - 1, 1);
            sb.Append(")").Append(Environment.NewLine).Append(';').Append(Environment.NewLine);
        }

        protected override void StartInsertData()
        {
            sb.Append("insert into ");
            if (string.IsNullOrEmpty(table.Prefix) == false)
            {
                sb.Append(table.Prefix).Append('.');
            }
            sb.Append(table.Name).Append(' ');
        }

        protected override void StartInsertRow()
        {
            sb.Append("values(");
        }

        protected override void InsertValue(DbColumn column, string val)
        {
            if (val == null)
                val = string.Empty;

            switch (column.TFormat.TextType)
            {
                case TextTypeType.Integer:
                case TextTypeType.Long:
                case TextTypeType.Short:
                case TextTypeType.BigInteger:
                case TextTypeType.Decimal:
                case TextTypeType.Float:
                case TextTypeType.Double:
                    sb.Append(val);
                    break;

                case TextTypeType.Boolean:
                    if (val.ToLower() == "true" || val == "1")
                        sb.Append("1");
                    else
                        sb.Append("0");
                    break;

                case TextTypeType.Year:
                    if (val.Length > 4)
                        val = val.Substring(0, 4);
                    sb.Append(ValChar(val));
                    break;

                case TextTypeType.Date:
                    //TODO: See with Cedric fore more information
                    sb.Append(ValChar(val));
                    break;

                case TextTypeType.String:
                default:
                    // Trim val to maxlength
                    int len = GetCharColumnLen(column.TFormat);
                    if (val.Length > len)
                        val = val.Substring(0, len);
                    sb.Append(ValChar(val));
                    break;
            }
            sb.Append(',');
        }


        protected override void EndInsertRow()
        {
            sb.Remove(sb.Length - 1, 1);
            sb.Append(")").Append(Environment.NewLine);
        }

        protected override void EndInsertData()
        {
            sb.Append(';').Append(Environment.NewLine);
        }
        #endregion
    }
}
